﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using IronCow.UnitTests.Mock;

namespace IronCow.UnitTests
{
    [TestFixture]
    public class TestTaskTags
    {
        private MockRtm Rtm;

        [SetUp]
        public void SetUp()
        {
            Rtm = new MockRtm();
            Rtm.AddSuccessResponse("rtm.lists.getList",
                new MockListsResponsePart()
                {
                    new MockListResponsePart(987654321, "Inbox", TaskListFlags.Locked)
                });
        }

        [TearDown]
        public void TearDown()
        {
            Rtm = null;
        }

        [Test]
        public void TestAddTag()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                    {
                        new MockTaskSeriesResponsePart(1, "Get Bananas")
                        {
                            new MockTaskResponsePart(1)
                        }
                    }
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.addTags",
                new MockTaskListResponsePart(987654321)
                {
                    new MockTaskSeriesResponsePart(1, "Get Bananas")
                    {
                        Tags = new string[] { "@errand" },
                        NestedParts = { new MockTaskResponsePart(1) }
                    }
                });

            TaskList inbox = Rtm.TaskLists[0];
            Assert.That(inbox.Tasks, Has.Count(1));
            Task task = inbox.Tasks[0];
            Assert.That(task.Tags, Has.Count(0));
            task.Tags.Add("@errand");
            Assert.That(task.Tags, Has.Count(1));
            Assert.AreEqual("@errand", task.Tags[0]);

            Rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestRemoveTag()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                    {
                        new MockTaskSeriesResponsePart(1, "Get Bananas")
                        {
                            Tags = new string[] { "@errand", "@home" },
                            NestedParts =  { new MockTaskResponsePart(1) }
                        }
                    }
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.removeTags",
                new MockTaskListResponsePart(987654321)
                {
                    new MockTaskSeriesResponsePart(1, "Get Bananas")
                    {
                        Tags = new string[] { "@errand" },
                        NestedParts = { new MockTaskResponsePart(1) }
                    }
                });

            TaskList inbox = Rtm.TaskLists[0];
            Assert.That(inbox.Tasks, Has.Count(1));
            Task task = inbox.Tasks[0];
            Assert.That(task.Tags, Has.Count(2));
            Assert.AreEqual("@errand", task.Tags[0]);
            Assert.AreEqual("@home", task.Tags[1]);
            task.Tags.Remove("@home");
            Assert.That(task.Tags, Has.Count(1));
            Assert.AreEqual("@errand", task.Tags[0]);

            Rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestSetTag()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                    {
                        new MockTaskSeriesResponsePart(1, "Get Bananas")
                        {
                            Tags = new string[] { "@errand", "@market", "@home" },
                            NestedParts =  { new MockTaskResponsePart(1) }
                        }
                    }
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.setTags",
                new MockTaskListResponsePart(987654321)
                {
                    new MockTaskSeriesResponsePart(1, "Get Bananas")
                    {
                        Tags = new string[] { "@errand", "@market", "next" },
                        NestedParts = { new MockTaskResponsePart(1) }
                    }
                });

            TaskList inbox = Rtm.TaskLists[0];
            Assert.That(inbox.Tasks, Has.Count(1));
            Task task = inbox.Tasks[0];
            Assert.That(task.Tags, Has.Count(3));
            Assert.AreEqual("@errand", task.Tags[0]);
            Assert.AreEqual("@market", task.Tags[1]);
            Assert.AreEqual("@home", task.Tags[2]);
            task.Tags[2] = "next";
            Assert.That(task.Tags, Has.Count(3));
            Assert.AreEqual("@errand", task.Tags[0]);
            Assert.AreEqual("@market", task.Tags[1]);
            Assert.AreEqual("next", task.Tags[2]);

            Rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestCreateTaskWithTags()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.add",
                new MockTaskListResponsePart(987654321)
                {
                    new MockTaskSeriesResponsePart(987654321, "Get Bananas")
                    {
                        new MockTaskResponsePart(123456789)
                    }
                });
            Rtm.AddSuccessResponse("rtm.tasks.setTags",
                new MockTaskListResponsePart(987654321)
                {
                    new MockTaskSeriesResponsePart(987654321, "Get Bananas")
                    {
                        Tags = new string[] { "@errand", "next" },
                        NestedParts =
                        {
                            new MockTaskResponsePart(123456789)
                        }
                    }
                });

            Task task = new Task();
            task.Name = "Get Bananas";
            task.Tags.Add("@errand");
            task.Tags.Add("next");
            Assert.IsFalse(task.IsSynced);
            Assert.That(task.Tags, Has.Count(2));
            Assert.AreEqual("@errand", task.Tags[0]);
            Assert.AreEqual("next", task.Tags[1]);

            TaskList list = Rtm.TaskLists[0];
            Assert.AreEqual(0, list.Tasks.Count);
            list.Tasks.Add(task);
            Assert.IsTrue(task.IsSynced);
            Assert.AreEqual(1, list.Tasks.Count);
            Assert.AreEqual("Get Bananas", task.Name);
            Assert.That(task.Tags, Has.Count(2));
            Assert.AreEqual("@errand", task.Tags[0]);
            Assert.AreEqual("next", task.Tags[1]);

            Rtm.EnsureAllResponsesUsed();
        }
    }
}
